package com.yesallchina.wxapp.officialaccount.api;


import com.yesallchina.wxapp.officialaccount.api.beans.*;
import com.yesallchina.wxapp.officialaccount.api.enums.MessageEventTypeEnum;
import com.yesallchina.wxapp.officialaccount.ext.BusinessMessageHandler;
import com.yesallchina.wxapp.officialaccount.service.WxOfficialAccountInitializer;
import com.yesallchina.wxapp.officialaccount.utils.JacksonUtils;
import com.yesallchina.wxapp.officialaccount.utils.WxHttpUtils;
import com.yesallchina.wxapp.officialaccount.utils.XmlUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 *
 * 消息管理
 *
 */
public class MessageApi {

    private ExecutorService exec = Executors.newFixedThreadPool(5);

    private WxOfficialAccountInitializer wxInit;

    private BasicSupportApi basicSupportApi;

    public MessageApi(BasicSupportApi basicSupportApi) {
        this.wxInit = basicSupportApi.getWxInit();
        this.basicSupportApi = basicSupportApi;
    }

    public WxOfficialAccountInitializer getWxInit() {
        return wxInit;
    }

    public BasicSupportApi getBasicSupportApi() {
        return basicSupportApi;
    }

    /**
     * 接收微信公众号会话信息并进行处理后返回
     *
     * @param xml
     * @return
     */
    public String receive(String xml) {
        if (!StringUtils.hasText(xml)) {
            return "";
        }
        Message message = XmlUtils.xmlToMessageBean(xml);
        // 使用该扩展的接口自定义处理消息
        BusinessMessageHandler handler = wxInit.getAppCtx().getBean(wxInit.getSpiProp().getMessageHandlerName());
        if (handler == null) {
            return "";
        }
        List<Message> messages = handler.handle(message);
        if (CollectionUtils.isEmpty(messages)) {
            return "";
        }
        return handleMessage(messages, message.getFromUserName());
    }

    /**
     * 响应消息处理
     *
     * @param messages
     * @param toUserName
     * @return
     */
    private String handleMessage(final List<Message> messages, final String toUserName) {
        if (messages.size() == 1) {
            return XmlUtils.beanToXml(messages.get(0));
        }
        Message message = messages.remove(0);
        exec.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    // 保证按序发出
                    TimeUnit.SECONDS.sleep(1);
                } catch (Exception e) {
                }
                for (Message reply : messages) {
                    reply.setFromUserName(wxInit.getCommonProp().getPublicId());
                    reply.setToUserName(toUserName);
                    // 如果是图文消息，腾讯微信服务限制图文消息只能有8条
                    reply = chkNewsMessage(reply);
                    sendCustomeMessage(reply);
                }
            }
        });
        return XmlUtils.beanToXml(message);
    }

    private Message chkNewsMessage(Message message) {
        if (MessageEventTypeEnum.NEWS.getMsgType().equalsIgnoreCase(message.getMsgType())) {
            NewsMessage news = (NewsMessage) message;
            if (news.getArticleCount() > 8) {
                List<Article> articles = news.getArticles().subList(0, 8);
                news.setArticles(articles);
                news.setArticleCount(8);
            }
            return news;
        }
        return message;
    }

    /**
     *
     * 发送客服消息
     *
     * @param message
     */
    public void sendCustomeMessage(Message message) {
        String url = wxInit.getApiProp().getMsgSendCustom()
                + "?" + ParamName.ACCESS_TOKEN + "=" + basicSupportApi.getAccessToken();
        message =  chkNewsMessage(message);
        WxHttpUtils.postJSON(url, message.toCustomerMessage(), wxInit.getCommonProp());
    }

    public void sendCustomeMessage(List<Message> messages){
        for (Message reply : messages) {
            // 如果是图文消息，腾讯微信服务限制图文消息只能有8条
            reply = chkNewsMessage(reply);
            sendCustomeMessage(reply);
            try {
                // 保证按序发出
                TimeUnit.SECONDS.sleep(1);
            } catch (Exception e) {
            }
        }
    }

    /**
     * 发送模板消息
     *
     */
    public void sendTplMessage(TemplateMessage message){
        String url = wxInit.getApiProp().getMsgSendTpl()
                + "?" + ParamName.ACCESS_TOKEN + "=" + basicSupportApi.getAccessToken();
        WxHttpUtils.postJSON(url, JacksonUtils.generate(message), wxInit.getCommonProp());
    }




}
